import { _decorator, Component, Node ,director, input,Input,KeyCode,EventKeyboard,find, Prefab, instantiate, assert} from 'cc';
import { TankMove } from './Game/TankMove';
import { DIR } from './Common';
import { TankShoot } from './Game/TankShoot';
import { AudioMgr } from '../AudioMgr/AudioMgr';
import { EventMgr } from '../EventMgr/EventMgr';
import { TankAI } from './Game/TankAI';
import { Healthy } from './Game/Healthy';
import { StagePanel } from './UI/StagePanel';
import { TankCreate } from '../scripts/Game/TankCreate';
import { Root } from './Root';
const { ccclass, property } = _decorator;

@ccclass('GameMgr')
export class GameMgr extends Component {

    @property([Prefab])
    propGoList:Prefab[]=[];


    @property({type:[TankAI],visible:true})
    enemyAIList:TankAI[]=[];

    @property(Prefab)
    pGo:Prefab|null=null;
    private player:Node|null=null;
    @property playerLifeCount:number=3;

   
    static Inst:GameMgr|null=null;
    

    private tankCreates:TankCreate[]=null;
    private stagePanel:StagePanel|null=null;


    //非gameover包括胜利和进行中
    gameOverState:boolean=false;

    protected onLoad(): void {

        this.tankCreates=find("Canvas/enemyPoints").getComponentsInChildren(TankCreate);
        console.log("tankCreatesCount:"+this.tankCreates.length);
        this.stagePanel=find("Canvas/ui_stage").getComponent(StagePanel);


        //重置一下
        GameMgr.Inst=null;
        if(GameMgr.Inst===null){
         GameMgr.Inst=this;
        }

        input.on(Input.EventType.KEY_DOWN, this._onKeyDown, this);
        input.on(Input.EventType.KEY_UP, this._onKeyUp, this);

        EventMgr.Inst.addEvent("GAME_OVER",this.gameOver,this);
        EventMgr.Inst.addEvent("GAME_WIN",this.gameWin,this);
        EventMgr.Inst.addEvent("GAME_START",this.gameStart,this);
    }
    protected onDestroy(): void {
        input.off(Input.EventType.KEY_DOWN, this._onKeyDown, this);
        input.off(Input.EventType.KEY_UP, this._onKeyUp, this);
        
        EventMgr.Inst.removeEvent("GAME_OVER",this.gameOver,this);
        EventMgr.Inst.removeEvent("GAME_WIN",this.gameWin,this);
        EventMgr.Inst.removeEvent("GAME_START",this.gameStart,this);
    }
    addPlayerLifeCount(){

        this.playerLifeCount+=1;
        console.log("lifeCount:"+this.playerLifeCount);
    }
    createPlayer(){
        this.player=null;
        this.scheduleOnce(()=>{
        if(this.playerLifeCount>0){
          console.log("createPlayer");
       let go:Node= instantiate(this.pGo);
       find("Canvas/players").addChild(go);
       go.setPosition(-5,-115);

       this.player=go;

        this.playerLifeCount-=1;

        }else {
            EventMgr.Inst.sendEvent("GAME_OVER");
        }

        },0.2)
    }

    //限制敌人数量，避免一下生一大堆。
    limitEnemyCount_continue():boolean{

        //这里限制有问题
        const limitCount=6;
        if(this.enemyAIList.length>=limitCount){
           return false;
        }else {
            return true;
        }
    }


    addEnemyAI(ai:TankAI){
        this.enemyAIList.push(ai);
    }

    removeEnemyAI(ai:TankAI){
     //   console.log("del ai and count "+this.enemyAIList.length);
        this.enemyAIList.splice(this.enemyAIList.indexOf(ai),1);

       this.isGameWIN(this.tankCreates);
    }


    //tankCreates是缓存没有问题，但它的数量是在变化的。
    isGameWIN(tankCreates:TankCreate[]){
        if(this.gameOverState===true) return;

        let totalSum =0;
        for(let i=0;i<tankCreates.length;i++){
            let item:TankCreate=tankCreates[i];
            totalSum+=item.getCreateCount();
        }


        let isWIN:boolean= (this.enemyAIList.length===0) && (totalSum===0);
        if(isWIN){
            EventMgr.Inst.sendEvent("GAME_WIN");
        }
    }

    gameWin(){
        Root.Inst.addSceneLv();
        console.log("game win");
        this.scheduleOnce(()=>{
            Root.Inst.loadNextLv();
        },2.5);
    }

    destoryAllEnemy(){
        for(let item of this.enemyAIList){
            item.getComponent(Healthy).reduceHp(10000)
        }
    }

    pauseAI():void{
        for(let item of this.enemyAIList){
            item.stopAllExe(true);
        }
        this.scheduleOnce(()=>{

        for(let item of this.enemyAIList){
            item.stopAllExe(false);
        }
        },15);
    }


    getCurSceneLv():number{
        return Root.Inst.curSceneLv;
    }

    getQuickTime(t:number,testT?:number){
        if(Root.Inst.isRelease){
            return t;
        }else {
            if(testT===undefined){
                return 0;
            }else {
                return testT;
            }
        }
    }

    protected start(): void {
        //console.log("game mgr start");

        this.createPlayer();
        this.stagePanel.gameStart(()=>{
            EventMgr.Inst.sendEvent("GAME_START");
            console.log("gStart");
        });
        //this.gameStart();
    }
    gameStart(){
      //  this.createPlayer();
        AudioMgr.Inst.playMusicSync("player_move");
        AudioMgr.Inst.setMusicVolume(0);
        AudioMgr.Inst.playEffectSync("start");
    }

    gameOver(){
        //director.pause();
        this.gameOverState=true;
        //这里复现还有有大概率
        AudioMgr.Inst.setMusicVolume(0);
        console.log("game over");

        //todo 这里问题很大特别ondestory
        this.scheduleOnce(()=>{
            director.loadScene("menu-001");
        },2.5);
    }



    _onKeyDown(event: EventKeyboard ) {
        if(this.player==null)return;

        AudioMgr.Inst.setMusicVolume(1);
        let tm:TankMove=this.player.getComponent(TankMove);
        let ts:TankShoot=this.player.getComponent(TankShoot);

        switch (event.keyCode) {
            case KeyCode.KEY_A:
        tm.changeMoveState(true);
                tm.changeDir(DIR.left);
                break;
            case KeyCode.KEY_W:
        tm.changeMoveState(true);
                tm.changeDir(DIR.top);
                break;
            case KeyCode.KEY_D:
        tm.changeMoveState(true);
                tm.changeDir(DIR.right);
                break;
            case KeyCode.KEY_S:
        tm.changeMoveState(true);
                tm.changeDir(DIR.bottom);
                break;
            case KeyCode.KEY_J:
                //console.log("j"+ts);
                ts.shoot();
                break;
            case KeyCode.KEY_L:
                break;
            case KeyCode.KEY_K:
            default:
                break;
        }
       
    }

    _onKeyUp(event: EventKeyboard) {
        if(this.player==null)return;

        AudioMgr.Inst.setMusicVolume(0);
        let tm:TankMove=this.player.getComponent(TankMove);

        switch (event.keyCode) {
            case KeyCode.KEY_A:
        tm.changeMoveState(false);
                break;
            case KeyCode.KEY_W:
        tm.changeMoveState(false);
                break;
            case KeyCode.KEY_D:
        tm.changeMoveState(false);
                break;
            case KeyCode.KEY_S:
        tm.changeMoveState(false);
                break;
            case KeyCode.KEY_K:
            default:
                break;
        }
        
    }
}


